package xyz.xuetu.www.rpc.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.setting.dialect.Props;
import cn.hutool.setting.yaml.YamlUtil;
import io.netty.util.internal.StringUtil;
import xyz.xuetu.www.rpc.config.RpcConfig;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

/**
 * 配置工具类
 */
public class ConfigUtils {

    /**
     * 加载配置对象
     * @param tClass
     * @param prefix
     * @return
     * @param <T>
     */
    public static <T> T loadConfig(Class<T> tClass, String prefix) {
        return loadConfig(tClass, prefix, "");
    }

    /**
     * 加载配置对象，支持分区环境
     * @param tClass
     * @param prefix
     * @param environment
     * @return
     * @param <T>
     */
    public static <T> T loadConfig(Class<T> tClass, String prefix, String environment) {
        StringBuilder sb = new StringBuilder();
        sb.append("application");
        if(!StringUtil.isNullOrEmpty(environment)) {
            sb.append("-").append(environment);
        }
        String propertiesSuffix = ".properties";
        String ymlSuffix = ".yml";
        String yamlSuffix = ".yaml";
        T oldImplClass = loadRpcConfigFromProperties(sb.toString().concat(propertiesSuffix), prefix, tClass);
        T newImplClass = loadRpcConfigFromYml(sb.toString().concat(ymlSuffix), prefix, tClass);
        BeanUtil.copyProperties(newImplClass, oldImplClass, true);
        newImplClass = loadRpcConfigFromYml(sb.toString().concat(yamlSuffix), prefix, tClass);
        BeanUtil.copyProperties(newImplClass, oldImplClass, true);
        return oldImplClass;
    }

    /**
     * 从指定的 Properties 文件中加载 RpcConfig
     * @param fileName
     * @param prefix
     * @param tClass
     * @return
     * @param <T>
     */
    private static <T> T loadRpcConfigFromProperties(String fileName, String prefix, Class<T> tClass) {
        Props props = new Props(fileName);
        return props.toBean(tClass, prefix);
    }

    /**
     * 从指定的 Yml 文件中加载 RpcConfig
     * @param fileName
     * @param prefix
     * @param tClass
     * @return
     * @param <T>
     */
    private static <T> T loadRpcConfigFromYml(String fileName, String prefix, Class<T> tClass) {
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
        Reader reader = new InputStreamReader(is);
        Map<String, Object> load = YamlUtil.load(reader);
        Map<String, Object> rpcConfigMap = (Map<String, Object>) load.get(prefix);
        return BeanUtil.mapToBean(rpcConfigMap, tClass, true, CopyOptions.create());
    }

}
